﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace hse_2013_272_lines
{
    public partial class MainForm : Form
    {
        //Действующие лица: поле, занимающееся логикой, графобъект, занимающийся отрисовкой на форме и буферное изображение.
        public Field field { get; private set; }
        Graphics g;
        Image fieldImage = new Bitmap(768, 1024);
        
        public MainForm()
        {
            this.PreviewKeyDown += new PreviewKeyDownEventHandler(MainForm_PreviewKeyDown);//Я вообще не шарю в событиях, но в МСДН так, значит, пусть
            this.KeyDown += new KeyEventHandler(MainForm_KeyDown);                         //так и будет
            this.KeyDown += new KeyEventHandler(MainForm_Pause); // MainForm_Keydown проще всего отламывать во время паузы, а Esc должен работать и в паузе, так что они обрабатываются отдельно.
            InitializeComponent();
            g = this.CreateGraphics();
            label1.Text = "";
            NewGame();
        }

        

        //Новая игра
        void NewGame()
        {
            //Формирование нового поля
            field = new Field(GameOver, Redraw);
        }

        //Ход игры
        void Redraw()
        {
            // Финт ушами: сначала мы рисуем поле в памяти, предоставляя всем желающим fieldImage как объект рисования, а потом одномоментно выводим его на форму.
            var fieldGraphics = Graphics.FromImage(fieldImage);
            field.Draw(fieldGraphics);
            g.DrawImage(fieldImage, 0,0);

            //Обновляем очки/линии/уровень

            label4.Text = "Очки: " + field.score;
            label3.Text = "Линии: " + field.lines;
            label2.Text = "Уровень: " + field.speed;
        }

        //Приостановка игры
        private void MainForm_Pause(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
                    if (!field.paused)
                    {
                        //Перестаём реагировать на стрелки
                        KeyDown -= new KeyEventHandler(MainForm_KeyDown);
                        //Останавливаем падение
                        field.Pause();
                        //Отображаем паузу
                        label1.Text = "Пауза";
                        this.Redraw();
                    }
                    else
                    {
                        //Возобновляем падение
                        field.Continue();
                        //Снова реагируем на стрелки
                        KeyDown += new KeyEventHandler(MainForm_KeyDown);
                        field.paused = false;
                        //Не отображаем паузу
                        label1.Text = "";
                    }
                    break;

            }
        }

        //Конец игры
        private void GameOver()
        {
            field.Pause();
            //Перестаём реагировать на клавиши
            KeyDown -= new KeyEventHandler(MainForm_KeyDown);
            KeyDown -= new KeyEventHandler(MainForm_Pause);
            KeyDown += new KeyEventHandler(MainForm_Restart);
            //Какой-то вывод соообщений пользователю, мб сохранение результата и переход к нажатию на новую игру
            label1.ForeColor = Color.Red;
            label1.Text = "Конец игры";
            this.Redraw();
        }

        private void Restart()
        {
            label1.Text = "";
            NewGame();
        }

        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Down:
                    field.TryToMoveDown();
                    break;
                //Смещение влево    
                case Keys.Left:
                    field.TryToMoveLeft();
                    break;
                //Смещение вправо
                case Keys.Right:
                    field.TryToMoveRight();
                    break;
                //Поворот
                case Keys.Up:
                    field.TryToRotate();
                    break;
            }
        }

        private void MainForm_Restart(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                // Ещё раз?
                case Keys.R:
                    this.KeyDown += new KeyEventHandler(MainForm_KeyDown);                         //так и будет
                    this.KeyDown += new KeyEventHandler(MainForm_Pause); // MainForm_Keydown проще всего отламывать во время паузы, а Esc должен работать и в паузе, так что они обрабатываются отдельно.
                    this.KeyDown -= MainForm_Restart;
                    Restart();
                    break;
            }
        }

        //Этот коварный кусок кода позволяет считывать нажатия стрелок "против воли" системы
        private void MainForm_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                case Keys.Down:
                case Keys.Left:
                case Keys.Right:
                case Keys.Escape:
                    e.IsInputKey = true;
                    break;
            }
        }
    }
}
